-----------------------------------------------------------------------------
--
-- Module      :  Main
-- Copyright   :
-- License     :  AllRightsReserved
--
-- Maintainer  :  Eduard Sergeev
-- Stability   :  Highly Experimental
-- Portability :
--
-- |
--
-----------------------------------------------------------------------------
{-# LANGUAGE MultiParamTypeClasses, TypeOperators, FlexibleContexts,
TemplateHaskell, TypeFamilies #-}


module Main (

main

) where

import Data.Unit.Types
import Data.Unit.Metric
import Data.Unit.Tests.TypeTests
import Data.Unit.Instances
import Data.Unit.Generator

import qualified Prelude as P
import Prelude (Fractional, undefined, String, Int, Show, show, (++), error, print, read, (==), (/=), fst, snd, unlines, otherwise)
import Data.List (map, unionBy, lookup, intersperse, filter)
import Data.Function
import Data.Foldable
import Data.Maybe
import Control.Arrow



$(um "e" "toe" "5")

ee = toe 5
e2 = ee*ee
e3 = e2/ee
eg = e2 * kilograms 10

s1 = show (undefined :: (U :*: M))
s21 = undefined :: (U :*: M :*: S)
s2 = show s21
s3 = show (undefined :: U)
s4 = show (undefined :: U :/: (U :*: S))


--
fi1 = undefined :: M
fi2 = undefined :: M :*: S
fi3 = undefined :: M :*: S :*: S
----f1 ::
--f1 = gshow fi1
--f2 = gshow fi2
--f3 = gshow fi3
------







testCases = ls ++ [t7]

main = do
    print (undefined :: (Greater Two One r) => r)
    print $ seconds 1 * metres 6 * seconds 7
    print $ P.all id testCases
    print [show t10, show t11, show t12, show t13, show t14]


u0 = undefined :: (U :*: M)
u1 = undefined :: Union (U :*: M) (U :*: M) r => r
u2 = undefined :: Union (U :*: M :*: S) (U :*: M) r => r



m1 = undefined :: (Mult (U :*: M) (U :*: M) r) => r
m2 = undefined :: (Mult (U :*: M :*: M) (U :*: M) r) => r
m3 = undefined :: (Mult (U :*: M :*: S) (U :*: M) r) => r
m4 = undefined :: (Mult (U :*: M :*: S) (U :*: M :*: S) r) => r
m5 = undefined :: (Mult (U :*: M :*: M :*: S) (U :*: M :*: S) r) => r

m10 = undefined :: Mult ((U :*: M) :/: (U :*: S)) (U :*: S) r => r
m11 = undefined :: Mult (U :*: S) ((U :*: M) :/: (U :*: S)) r => r
m12 = undefined :: Mult ((U :*: S) :/: (U :*: M)) ((U :*: M) :/: (U :*: S)) r => r
m13 = undefined :: Mult (U :*: S) ((U :*: M) :/: (U :*: S)) r => r
m14 = undefined :: Mult ((U :*: M) :/: (U :*: S)) (U :*: S) r => r

---




dn1 = undefined :: Div (U :*: M :*: M) (U :*: M) r => r
dn2 = undefined :: Div (U :*: M :*: M :*: S) (U :*: M) r => r
dn3 = undefined :: Div (U :*: M :*: M :*: S) (U :*: M :*: S) r => r
dn4 = undefined :: Div (U :*: M :*: M) (U :*: S) r => r
dn5 = undefined :: Div (U :*: M) (U :*: S) r => r
dn6 = undefined :: Div (U :*: M) (U :*: S :*: S) r => r
dn7 = undefined :: Div (U :*: M :*: S) (U :*: M :*: S) r => r


dn10 = undefined :: Div ((U :*: M) :/: (U :*: S)) ((U :*: M) :/: (U :*: S)) r => r
dn11 = undefined :: Div ((U :*: M) :/: (U :*: S)) ((U :*: S) :/: (U :*: M)) r => r

dn20 = undefined :: Div (U :*: S) ((U :*: M) :/: (U :*: S)) r => r
dn21 = undefined :: Div (U :*: M) ((U :*: M) :/: (U :*: S)) r => r

dn30 = undefined :: Div ((U :*: M) :/: (U :*: S)) (U :*: S) r => r
dn31 = undefined :: Div ((U :*: M) :/: (U :*: S)) (U :*: M) r => r



d1 = undefined :: (Div (U :*: M :*: M) (U :*: M) r) => r
d2 = undefined :: (Div (U :*: M) (U :*: M) r) => r
d3 = undefined :: (Div (U :*: M) (U :*: S) r) => r
d4 = undefined :: (Div (U :*: M :*: S) (U :*: S) r) => r
d5 = undefined :: (Div (U :*: M :*: S) (U :*: M) r) => r
d6 = undefined :: (Div ((U :*: M) :/: (U :*: S)) (U :*: M) r) => r
d61 = undefined :: (Div (U :*: M) (U :*: M :*: S) r) => r
d62 = undefined :: (Div ((U :*: M) :/: (U :*: S)) ((U :*: M) :/: (U :*: M)) r) => r
d7 = undefined :: (Div (U :*: M :/: U :*: S) (U :*: S) r) => r
d8 = undefined :: (Div (U :*: M) (U :*: S) ms, Div ms (U :*: S) r) => r

-- U*M / (M*S)

d10 = undefined :: (Div (U :*: M :*: S) (U :*: M :*: S) r) => r
d11 = undefined :: (Div (U :*: M :/: U :*: S) (U :*: S :/: U :*: M) r) => r
d12 = undefined :: (Div (U :*: M :/: U :*: S) (U :*: M :/: U :*: S) r) => r
----




t5 = metres 6 * seconds 7
t6 = metres 6 * metres 7
t7 = show (metres 6 * seconds 7) == show (seconds 7 * metres 6)
t81 = metres 6 * metres 4
t82 = seconds 7
t83 = t81 * t82




t10 = metres 20 / seconds 2
t11 = t10 * t10
t12 = t10 * seconds 10
t13 = (metres 20 / seconds 2) / seconds 1
t14 = t10 / seconds 1
t15 = t14 / t12

v1 = metres 50 / seconds 10
a1 = v1 / seconds 1
v2 = a1 * seconds 12
dist2 = v2 * seconds 66 

$(um "f" "feet" "6")

--toMetres :: Unit F P.Double -> Unit M P.Double
toMetres fs = fs / feetPerMetre
    where feetPerMetre = feet 3.28084 / metres 1

fe1 = feet 6.2 -- :: Unit F

me1 = toMetres fe1

se1 = seconds 5

app1 = (mpure (P.negate) <***> se1) + se1

li1 = mlift2M (P.**) se1 se1 -- :: Unit M P.Double


